home *** CD-ROM | disk | FTP | other *** search
- /************* Random poetry generator ***********************/
- /** **/
- /** poetry.c **/
- /** **/
- /** Copyright (C) Paul Gaze 1997 **/
- /** Please, notify me, if you make any **/
- /** changes to this file. **/
- /*************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
-
- #define DEBUG_MESSAGES 0
-
- //**************************************
- // Structures
- //**************************************
- typedef struct{
- char *String;
- int Subject,Object;
- }VERB;
-
- #define MAX_LINE_LENGTH 256
-
- #define GENDA_HE 0
- #define GENDA_SHE 1
- #define GENDA_IT 2
- #define GENDA_THEY 3
- #define GENDA_I 4
- #define GENDA_WE 5
-
- typedef struct{
- void *Next;
- char *String;
- }TYPE_DATA;
-
- typedef struct{
- char *String;
- int Genda;
- int NTypes;
- int *Types;
- }NOUN;
-
- typedef struct{
- int NQuality;
- NOUN *Quality;
- char *String;
- }TYPE;
-
- typedef struct{
- int NVerb;
- VERB *Verb;
- int NNoun;
- NOUN *Noun;
- int NExclamation;
- char **Exclamation;
- int NType;
- TYPE *Type;
- }POET;
-
- typedef struct{
- int N;
- NOUN *Noun;
- NOUN *Quality;
- char *String;
- int Genda;
- int HisGenda;
- int NTypes;
- int *Types;
- }THING;
-
- typedef struct{
- void *Next;
- void *Data;
- size_t Amount;
- }MEMBLOCK;
-
- //**************************************
- // Prototypes
- //**************************************
- POET *LoadPoet(char *name);
- void ErrorExit(char *message);
- void ComposePoem(char *output, POET *poet, int seed);
- int RND(int range);
- void SetGenda(THING *t);
- void NewThing(POET *p, THING *t);
- void ChooseQuality(POET *p, THING *t);
- void Replace(char *key, char *replacement, char *str);
- int FindLine(char **lines, int nlines, char *str);
- void *GetMem(size_t amount, char *ErrorMessage);
- char *CloneString(char *from);
- void FreeMem(void *data);
- void ReadNoun(char *from, NOUN *noun, POET *p);
- void IndentLine(char *line);
- int StringToBin(char *str);
- void ShowHelp(void);
- #define FAIL(message) {printf(message); goto fail;}
-
- //**************************************
- // Static data
- //**************************************
- char *He[]={"he","she","it","they","i","we"};
- char *Him[]={"him","her","it","them","me","us"};
- char *His[]={"his","her","its","their","my","our"};
- char *Himself[]={"himself","herself","itself","themselves","myself","ourselves"};
-
- // Constants
- int NumberLines=6,PrintWidth=60;
- char *SubStr,*ObjStr;
- MEMBLOCK *MemList=0;
- size_t TotalMemory=0;
-
- int main(int argc, char *argv[])
- {
- POET *poet;
- int j;
- char input;
- char *poem,*ss;
- int seed;
- time_t t;
-
- if(argc>1){
- if(!strcmp("?",argv[1]))ShowHelp();
- }
- if(argc==1)
- poet=LoadPoet("poet.txt");
- else
- poet=LoadPoet(argv[1]);
-
- // Allocate space for strings
- SubStr=(char *)GetMem(MAX_LINE_LENGTH*sizeof(char), "Couldnt allocate space for subject string\n");
- ObjStr=(char *)GetMem(MAX_LINE_LENGTH*sizeof(char), "Couldnt allocate space for object string\n");
-
- // Randomize timer
- time(&t);
- j=(int)t;
- srand(j);
-
- // GET OPTIONS
- for(j=2; j<argc; j++){
- ss=argv[j];
- if( (ss[0]=='-') || (ss[0]='/') ){
- switch(ss[1]){
- case 'L': case 'l':
- NumberLines=StringToBin(&ss[2]);
- break;
- case 'W': case 'w':
- PrintWidth=StringToBin(&ss[2]);
- break;
- case 'S': case 's':
- seed=StringToBin(&ss[2]);
- srand(seed);
- break;
- case '?': case 'H': case 'h':
- ShowHelp();
- break;
- default:
- break;
- }
- }else if(ss[0]=='?'){
- ShowHelp();
- }
- }
-
- if(!poet)ErrorExit("Couldnt load poet data\n");
- poem=(char *)GetMem(64000,"Ran out of memory allocating buffer to recieve poems\n");
- seed=0;
- do{
- ComposePoem(poem, poet, seed);
- printf("\n\n");
- printf(poem);
- printf("\nENTER TO CONTINUE - Q = QUIT\n");
- input=getchar();
- seed++;
- }while( (input!='q') && (input!='Q') );
-
- ErrorExit(0);
- return 1;
- }
-
- //***********************************************
- // Show programs help screen
- //***********************************************
- // Input: None
- // Output: None
- //***********************************************
- void ShowHelp(void)
- {
- printf( "Random Poetry Generator Copyright 1997 - Paul Gaze\n"
- "Version 1.00 "__DATE__"\n"
- "\n"
- "Syntax: poem <filename> options\n"
- "\n"
- "Options can any of the following:\n"
- " -Wnn Set Characters per line to nn (default 60)\n"
- " -Snn Set random number seed to nn. Normaly its set\n"
- " according to the current time\n"
- " -Lnn Set lines per poem to nn (default 6)\n"
- " ? Show this help screen\n"
- "\n"
- "filename is the name of the file containing the poetry data.\n"
- "If it isnt specified then the program will attempt to load\n"
- "a file called poet.txt\n"
- "\n"
- );
- ErrorExit("");
- }
-
- //***********************************************
- // Figure out the person of a noun, taking into
- // account if its quality is being used. Also
- // make list of types.
- //***********************************************
- // Input: Thing
- // Output: None
- //***********************************************
- void SetGenda(THING *t)
- {
- t->HisGenda=t->Noun->Genda;
- if(t->Quality){
- t->Genda=t->Quality->Genda;
- t->Types=t->Quality->Types;
- t->NTypes=t->Quality->NTypes;
- }else{
- t->Genda=t->Noun->Genda;
- t->Types=t->Noun->Types;
- t->NTypes=t->Noun->NTypes;
- }
- }
-
- //***********************************************
- // Randomly choose a noun
- //***********************************************
- // Input: Poet data & output for noun
- // Output: None
- //***********************************************
- void NewThing(POET *p, THING *t)
- {
- t->N=RND(p->NNoun);
- t->Noun=&p->Noun[t->N];
- t->Quality=0;
- SetGenda(t);
- }
-
- //***********************************************
- // Randomly choose a quality of a noun
- //***********************************************
- // Input: Poet data & thing to choose a
- // quality of
- // Output: None
- //***********************************************
- void ChooseQuality(POET *p, THING *t)
- {
- int j;
- TYPE *type;
-
- if(!t->Noun->NTypes){
- ErrorExit("Strangely this noun had no types\n");
- return;
- }
- j=RND(t->Noun->NTypes);
- type=&p->Type[t->Noun->Types[j]];
- if(!type->NQuality){
- return;
- }
- j=RND(type->NQuality);
- t->Quality=&type->Quality[j];
- SetGenda(t);
- }
- //***********************************************
- // Substitute string
- //***********************************************
- // Input: String to replace, replacement,
- // string to work on
- // Output: None
- //***********************************************
- void Replace(char *key, char *replacement, char *str)
- {
- char *from, *comp, *to;
- int j, nchar, move;
-
- for(; *str; str++){
- from=str;
- for(comp=key; *comp; comp++,from++){
- if(*comp!=*from)break;
- }
- if(*comp)continue;
-
- // MAKE SPACE TO PUT IN SUBSTITUTE
- move=strlen(replacement)-strlen(key);
- if(move>0){
- from=str+strlen(str);
- to=from+move;
- nchar=strlen(str)-strlen(key)+1;
- for(j=nchar; j; j--){
- *to=*from;
- to--; from--;
- }
- }else if(move<0){
- from=str+strlen(replacement);
- to=from+move;
- while(*from){
- *to++=*from++;
- }
- *to++=0;
- }
- memcpy(str, replacement, strlen(replacement) );
- }
- }
-
-
-
-
- //***********************************************
- // Create a random poem
- //***********************************************
- // Input: output for string, poet data &
- // seed form random number generator
- // Output: None
- //***********************************************
- void ComposePoem(char *output, POET *poet, int seed)
- {
- int verb,UseableVerbs,i,j,k,xx;
- char *ex,letter;
- VERB *v;
- THING sub,obj,temp;
- THING sub_last,obj_last;
-
- sub.String=SubStr;
- obj.String=ObjStr;
- NewThing(poet, &sub);
- NewThing(poet, &obj);
- sub_last.N=-1;
- sub_last.Quality=0;
- obj_last.N=-1;
- obj_last.Quality=0;
-
- *output=0;
- for(j=0; j<NumberLines; j++){
- do{
- v=poet->Verb;
- UseableVerbs=0;
- for(k=0; k<poet->NVerb; k++,v++){
-
- //***********************************************************
- #define CHECK_VERB \
- for(i=0; i<sub.NTypes; i++){ \
- if(sub.Types[i]==v->Subject)break; \
- } \
- if(i==sub.NTypes)continue; \
- for(i=0; i<obj.NTypes; i++){ \
- if(obj.Types[i]==v->Object)break; \
- } \
- if(i==obj.NTypes)continue;
- //***********************************************************
- CHECK_VERB
- UseableVerbs++;
- }
- if(!UseableVerbs){
- NewThing(poet, &sub);
- NewThing(poet, &obj);
- }
- }while(!UseableVerbs);
- verb=RND(UseableVerbs)+1;
- v=poet->Verb;
- for(v=poet->Verb; 1; v++){
- CHECK_VERB
- verb--;
- if(!verb)break;
- }
- if(RND(100)<33){
- ex=poet->Exclamation[RND(poet->NExclamation)];
- }else{
- ex=0;
- }
-
-
- // GET OBJECT STRING
- if(obj.N==obj_last.N && obj.Quality==obj_last.Quality){
- sprintf( obj.String, Him[obj.Genda]);
- }else{
- if(obj.Quality){
- sprintf(obj.String, "%s %s",His[obj.HisGenda],obj.Quality->String);
- }else{
- sprintf(obj.String, obj.Noun->String);
- }
- }
-
- // GET SUBJECT STRING
- if(sub.N==sub_last.N && sub.Quality==sub_last.Quality){
- sprintf( sub.String, He[sub.Genda]);
- }else{
- if(sub.Quality){
- sprintf(sub.String, "%s %s",His[sub.HisGenda],sub.Quality->String);
- }else{
- sprintf(sub.String, sub.Noun->String);
- }
- }
- if(ex){
- sprintf(output,"%s %s,\n", ex, v->String);
- }else{
- sprintf(output,"%s,\n", v->String);
- }
- Replace("*sub", sub.String, output);
- Replace("*psub", His[sub.Genda], output);
- Replace("*ref", Himself[sub.Genda], output);
-
- Replace("*obj", obj.String, output);
- Replace("*pobj", His[obj.Genda], output);
-
- // MAKE FIRST LETTER CAPITAL
- letter=*output;
- if( (letter>='a') && (letter<='z') )letter+=('A'-'a');
- *output=letter;
- IndentLine(output);
-
-
- output+=(strlen(output));
-
- sub_last=sub;
- obj_last=obj;
-
- // CHANGE OBJECT & SUBJECT
- xx=RND(100);
- if(xx<15){
- NewThing(poet, &obj);
- }else if(xx<30){
- NewThing(poet, &sub);
- }else if(xx<45){
- ChooseQuality(poet, &obj);
- }else if(xx<60){
- ChooseQuality(poet, &sub);
- }else if(xx<80){
- temp=sub;
- sub=obj;
- obj=temp;
- }
- }
- output-=2;
- *output='.';
- }
-
- //***********************************************
- // Return number in range 0 -> limit-1
- //***********************************************
- // Input: Range
- // Output: Random number
- //***********************************************
- int RND(int range)
- {
- return rand()%range;
- }
-
- //***********************************************
- // Format line to fit in display width
- //***********************************************
- // Input: String for line
- // Output: None
- //***********************************************
- void IndentLine(char *line)
- {
- char *indent="\n ";
- char *from,*to;
- int move,nchar,j;
-
- while(1){
- nchar=strlen(line);
- if(nchar<PrintWidth)break;
- j=PrintWidth;
- while( line[j]!=' ' ){
- j--;
- if(j<0)return;
- }
- line=&line[j];
- move=strlen(indent)-1;
- nchar=strlen(line)+1-1;
- from=&line[strlen(line)];
- to=&from[move];
- while(nchar){
- *to=*from;
- to--; from--;
- nchar--;
- }
- memcpy(line, indent, strlen(indent));
- line++;
- }
- }
- //***********************************************
- // Exit code with an error message
- //***********************************************
- // Input: Pointer to error message
- // Output: None
- //***********************************************
- void ErrorExit(char *message)
- {
- if(message)printf(message);
-
- // Free all memory
- while(MemList){
- FreeMem(MemList->Data);
- }
- #if DEBUG_MESSAGES
- printf("%d bytes left unfreed\n",(int)TotalMemory);
- #endif
- exit(1);
- }
- //***********************************************
- // Load data for poet from file
- //***********************************************
- // Input: File name
- // Output: Pointer to poet data
- //***********************************************
- POET *LoadPoet(char *name)
- {
- char *data=NULL,*from,*from2,*to,letter,*str,*str2;
- FILE *f=NULL;
- size_t length;
- int nline, blank, j, k, doneit, n, start, end, nletter;
- int iverb, sub_type, obj_type, finished;
- POET *p=0;
- char **line,*ss;
- NOUN *noun;
- VERB *v;
- TYPE_DATA *TypeData=0, *t;
- TYPE *tt;
-
- // SET UP INITIAL STRUCTURE
- p=(POET *)GetMem(sizeof(POET),"Couldnt allocate space for poet data\n");
- memset(p, 0, sizeof(POET));
-
- // LOAD IN DATA
- f=fopen(name,"rb");
- if(f==NULL)FAIL("Unable to open poet file\n");
- if(fseek(f, 0, SEEK_END))FAIL("Trouble reading poet file\n");
- length=ftell(f);
- data=(char *)GetMem(length+1, "Trouble allocating data to read poet file\n");
- if(fseek(f, 0, SEEK_SET))FAIL("Trouble reading poet file\n");;
- if(length!=fread(data, 1, length, f))FAIL("Trouble reading poet file\n");
- data[length]=0;
- fclose(f);
-
- // REMOVE ESCAPE CHARACTERS
- from=to=data;
- while( (letter=*from++) ){
- if(letter!=0x0d)
- *to++=letter;
- }
- *to++=0;
-
- // REMOVE COMMENTS & BLANK LINES
- from=to=data;
- while(1){
- letter=*from;
- if(!letter)break;
- if(letter==';'){
- while(1){
- letter=*from++;
- if( (letter=='\n') || (!letter) )break;
- }
- }else{
- blank=1;
- nline=0;
- from2=from;
- while(1){
- nline++;
- letter=*from2++;
- if( (letter=='\n') || (!letter) )break;
- if( (letter!=' ') && (letter!=' ') ){
- blank=0;
- }
- }
- if(!blank){
- memcpy(to, from, nline);
- to+=nline;
- }
- from+=nline;
- }
- }
- *to++=0;
-
- // DIVIDE INTO LINES
- nline=0;
- from=data;
- do{
- letter=*from++;
- if( (!letter) || (letter=='\n') ){
- nline++;
- }
- }while(letter);
- line=(char **)GetMem(nline*sizeof(char *), "Trouble allocating memory for poet file\n");
- from=data;
- for(j=0; j<nline; j++){
- line[j]=from;
- do{
- letter=*from++;
- if( (letter=='\n')||(!letter) )
- break;
- }while(1);
- from--;
- *from++=0;
- }
-
- // GET RID OF GARBAGE AT END OF LINE
- for(j=0; j<nline; j++){
- from=line[j];
- n=strlen(from);
- doneit=0;
- for(;n>=0;n--){
- letter=from[n];
- switch(letter){
- case 0: case ' ':case ' ':
- from[n]=0;
- break;
- default:
- doneit=1;
- break;
- }
- if(doneit)break;
- }
- }
-
- //////////////////////////////////////
- // //
- // GET TYPES //
- // //
- //////////////////////////////////////
- p->NType=0;
- for(j=0; j<nline; j++){
- str=line[j];
- str=strstr(str,"/");
- if(!str)continue;
- do{
- str2=strstr(str+1,"/");
- if(!str2)break;
- nletter=((int)str2)-((int)str)+1;
- for(t=TypeData; t; t=(TYPE_DATA *)t->Next){
- if(nletter!=strlen(t->String))continue;
- if( !memcmp(str,t->String,nletter) )break;
- }
- if(!t){
- p->NType++;
- t=(TYPE_DATA *)GetMem(sizeof(TYPE_DATA), 0);
- t->Next=TypeData;
- TypeData=t;
- t->String=(char *)GetMem(nletter+1, 0);
- memcpy(t->String, str, nletter);
- t->String[nletter]=0;
- }
- str=str2;
- }while(1);
- }
- p->Type=(TYPE *)GetMem(p->NType*sizeof(TYPE), 0);
- memset(p->Type, 0, p->NType*sizeof(TYPE));
- t=TypeData;
- for(j=0; j<p->NType; j++){
- p->Type[j].String=t->String;
- t=(TYPE_DATA *)t->Next;
- }
-
- //////////////////////////////////////
- // //
- // READ EXCLAMATIONS //
- // //
- //////////////////////////////////////
- start=FindLine(line, nline, "&EXCLAMATIONS");
- if(start==nline)FAIL("Couldnt find &EXCLAMATIONS\n");
-
- end=FindLine(line, nline, "&ENDEXCLAMATIONS");
- if(end==nline)FAIL("Couldnt find &ENDEXCLAMATIONS\n");
- p->NExclamation=end-start-1;
- if(p->NExclamation<=0)FAIL("Dodgy exclamation data\n");
-
- p->Exclamation=(char **)GetMem(p->NExclamation*sizeof(char *), "Trouble allocating memory for exclamation data\n");
- for(j=0; j<p->NExclamation; j++){
- from=line[start+j+1];
- p->Exclamation[j]=(char *)GetMem(strlen(from) + 1, "Couldnt allocate memory for exclamation data\n");
- strcpy(p->Exclamation[j], from);
- }
-
- //////////////////////////////////////
- // //
- // GET NOUNS //
- // //
- //////////////////////////////////////
- start=FindLine(line, nline, "&NOUNS");
- if(start==nline)FAIL("Couldnt find &NOUNS\n");
- end=FindLine(line, nline, "&ENDNOUNS");
- if(end==nline)FAIL("Couldnt find &ENDNOUNS\n");
- p->NNoun=end-start-1;
- if(p->NNoun<=0)FAIL("No nouns found\n");
-
- noun=p->Noun=(NOUN *)GetMem(p->NNoun*sizeof(NOUN), "Ran out of memory\n");
- for(j=0; j<p->NNoun; j++, noun++){
- from=line[start+j+1];
- ReadNoun(from, noun, p);
-
- }
-
- //////////////////////////////////////
- // //
- // GET VERBS //
- // //
- //////////////////////////////////////
- start=FindLine(line, nline, "&VERBS");
- if(start==nline)FAIL("Couldnt find &VERBS\n");
- end=FindLine(line, nline, "&ENDVERBS");
- if(end==nline)FAIL("Couldnt find &ENDVERBS\n");
-
- // COUNT VERBS & ALLOCATE SPACE FOR THEM
- p->NVerb=0;
- for(j=start+1; j<end; j++){
- if(!strstr(line[j],"/")){
- p->NVerb++;
- }
- }
- if(!p->NVerb)FAIL("There arent any verbs\n");
- v=p->Verb=(VERB *)GetMem(p->NVerb*sizeof(VERB), "Ran out of space allocating memory for verbs\n");
- j=start+1;
- iverb=0;
- finished=0;
- while(!finished){
- if(!strstr(line[j],"/"))FAIL("corrupt verb data 1\n");
- sub_type=obj_type=-1;
- for(k=0; k<p->NType; k++){
- str=strstr(line[j],p->Type[k].String);
- if(!str)continue;
- if(str==line[j])sub_type=k;
- ss=line[j]+1;
- str=strstr(line[j],p->Type[k].String);
- if(str)obj_type=k;
- }
- if( (sub_type==-1)||(obj_type==-1) ){
- if(sub_type!=-1)printf("Subject = %s\n",p->Type[sub_type].String);
- if(obj_type!=-1)printf("Object = %s\n",p->Type[obj_type].String);
- FAIL("Corrupt verb data 2\n");
- }
- j++;
- while(!strstr(line[j],"/")){
- v->String=CloneString(line[j]);
- v->Subject=sub_type;
- v->Object=obj_type;
- v++;
- iverb++;
- if(iverb==p->NVerb){
- finished=1;
- break;
- }
- j++;
- }
- }
- // MAKE SURE ALL VERBS HAVE SUBJECT & OBJECT
- v=p->Verb;
- for(j=0; j<p->NVerb; j++,v++){
- k=0;
- if(!strstr(v->String,"*sub"))k+=5;
- if(!strstr(v->String,"*obj"))k+=5;
- if(k){
- to=(char *)GetMem(strlen(v->String)+k+1,"Low memory\n");
- *to=0;
- if(!strstr(v->String,"*sub"))
- strcat(to,"*sub ");
- strcat(to, v->String);
- if(!strstr(v->String,"*obj"))
- strcat(to," *obj");
- FreeMem(v->String);
- v->String=to;
- }
- }
-
- //////////////////////////////////////
- // //
- // GET QUALITIES //
- // //
- //////////////////////////////////////
- start=FindLine(line, nline, "&QUALITIES");
- if(start==nline)FAIL("Couldnt find &QUALITIES\n");
- end=FindLine(line, nline, "&ENDQUALITIES");
- if(end==nline)FAIL("Couldnt find &ENDQUALITIES\n");
- j=start+1;
- while(j<end){
- if( strstr(line[j],"(") )FAIL("Corrupt quality data\n");
- for(k=0; k<p->NType; k++){
- if(!strcmp(p->Type[k].String,line[j]))break;
- }
- if(k==p->NType)FAIL("Failed to find type\n");
- tt=&p->Type[k];
-
- // COUNT NUMBER OF QUALITIES
- tt->NQuality=0;
- k=j+1;
- while(strstr(line[k],"(")){
- tt->NQuality++;
- k++;
- if(k==end)break;
- }
- noun=tt->Quality=(NOUN *)GetMem(tt->NQuality*sizeof(NOUN), 0);
- for(k=0; k<tt->NQuality; k++){
- ReadNoun(line[k+j+1], noun, p);
- noun++;
- }
- j+=(tt->NQuality+1);
- }
-
- return p;
- fail:
- ErrorExit("Couldnt load poet\n");
- return 0;
- }
-
- //***********************************************
- // Make a copy of a string
- //***********************************************
- // Input: String to copy
- // Output: Copy of string
- //***********************************************
- char *CloneString(char *from)
- {
- char *to;
-
- to=(char *)GetMem(strlen(from)+1, 0);
- strcpy(to, from);
- return to;
- }
-
-
- //***********************************************
- // Find line equal to given string
- //***********************************************
- // Input: list of lines, number of lines &
- // string to be searched for.
- // Output: number of line on which string is
- // to be found or nlines if it isnt
- // found.
- //***********************************************
- int FindLine(char **lines, int nlines, char *str)
- {
- int j;
-
- for(j=0; j<nlines; j++){
- if(!strcmp(str, lines[j]))break;
- }
- return j;
- }
-
- //***********************************************
- // Allocate memory
- //***********************************************
- // Input: Amount to allocate & message to
- // print if allocation fails
- // Output: pointer to memory allocated
- //***********************************************
- void *GetMem(size_t amount, char *ErrorMessage)
- {
- void *data=NULL;
- MEMBLOCK *mb=NULL;
-
- data=malloc(amount);
- if(data==NULL)goto fail;
- mb=(MEMBLOCK *)malloc(sizeof(MEMBLOCK));
- if(mb==NULL)goto fail;
- mb->Data=data;
- mb->Amount=amount;
- mb->Next=MemList;
- MemList=mb;
- TotalMemory+=amount;
- return data;
- fail:
- if(data!=NULL)free(data);
- if(mb!=NULL)free(mb);
- if(ErrorMessage)printf(ErrorMessage);
- printf("Couldnt allocate %d bytes\n",(int)amount);
- ErrorExit("Ran out of memory\n");
- }
-
- //***********************************************
- // Free memory
- //***********************************************
- // Input: Pointer to memory to free
- // Output: None
- //***********************************************
- void FreeMem(void *data)
- {
- MEMBLOCK *m,*last;
-
- m=MemList;
- if(m->Data==data){
- MemList=(MEMBLOCK *)m->Next;
- }else{
- last=m;
- m=(MEMBLOCK *)m->Next;
- while(m){
- if(m->Data==data)break;
- last=m;
- m=(MEMBLOCK *)m->Next;
- }
- if(!m)ErrorExit("Tried to free non existant memory block\n");
- last->Next=m->Next;
- }
- TotalMemory-=m->Amount;
- free(m->Data);
- free(m);
- }
-
- //***********************************************
- // Read data for noun out of string
- //***********************************************
- // Input: Data, output for noun & poet data
- // Output: None
- //***********************************************
- void ReadNoun(char *from, NOUN *noun, POET *p)
- {
- char *str;
- int nletter, n, k;
-
- // GET GENDA
- if( strstr(from,"(he)") ){
- noun->Genda=GENDA_HE;
- }else if( strstr(from,"(she)") ){
- noun->Genda=GENDA_SHE;
- }else if( strstr(from,"(it)") ){
- noun->Genda=GENDA_IT;
- }else if( strstr(from,"(they)") ){
- noun->Genda=GENDA_THEY;
- }else if( strstr(from,"(i)") ){
- noun->Genda=GENDA_I;
- }else if( strstr(from,"(we)") ){
- noun->Genda=GENDA_WE;
- }else{
- printf("Trouble on line:\n%s\n",from);
- FAIL("Couldnt find genda of noun\n");
- }
-
- // GET STRING
- str=from;
- nletter=0;
- while(*str){
- if(*str=='(')break;
- str++;
- nletter++;
- }
- if(!*str)FAIL("Couldnt get noun string\n");
- noun->String=(char *)GetMem(nletter+1, 0);
- noun->String[nletter]=0;
- memcpy(noun->String, from, nletter);
-
- // COUNT TYPES & ALLOCATE SPACE FOR THEM
- str=from;
- noun->NTypes=0;
- while(*str){
- if(*str=='/')noun->NTypes++;
- str++;
- }
- noun->NTypes--;
- if(!noun->NTypes)FAIL("No types found for verb\b");
- noun->Types=(int *)GetMem(noun->NTypes*sizeof(int), 0);
-
- // SET TYPES ARRAY
- str=from;
- k=0;
- for(n=0; n<p->NType; n++){
- if(strstr(from, p->Type[n].String)){
- if(k==noun->NTypes)FAIL("Something went wrong\n");
- noun->Types[k]=n;
- k++;
- }
- }
-
- for(n=0; n<noun->NTypes; n++){
- k=noun->Types[n];
- }
- return;
- fail:
- ErrorExit("It went wrong\n");
- }
-
- //***********************************************
- // Convert ASCII string to integer value
- //***********************************************
- // Input: String
- // Output: Value
- //***********************************************
- int StringToBin(char *str)
- {
- int sum=0,letter;
-
- while( (letter=*str++) ){
- letter-='0';
- if( (letter<0)||(letter>9) )break;
- sum=(sum*10)+letter;
- }
- return sum;
- }
-